package cn.outsourcing.supermarket.service.impl;

import cn.outsourcing.supermarket.common.CommonPage;
import cn.outsourcing.supermarket.common.PageResult;
import cn.outsourcing.supermarket.common.Result;
import cn.outsourcing.supermarket.common.constants.CommonConstants;
import cn.outsourcing.supermarket.common.constants.PayConstants;
import cn.outsourcing.supermarket.common.enums.OrderStatusEnums;
import cn.outsourcing.supermarket.common.enums.OrderTypeEnums;
import cn.outsourcing.supermarket.common.properties.WechatProperties;
import cn.outsourcing.supermarket.common.utils.*;
import cn.outsourcing.supermarket.converter.HiolabsOrderConverter;
import cn.outsourcing.supermarket.converter.transform.TimestampTransform;
import cn.outsourcing.supermarket.dto.DeleteOrderDTO;
import cn.outsourcing.supermarket.dto.OrdersPageDTO;
import cn.outsourcing.supermarket.mapper.HiolabsOrderMapper;
import cn.outsourcing.supermarket.po.HiolabsOrder;
import cn.outsourcing.supermarket.service.HiolabsOrderGoodsService;
import cn.outsourcing.supermarket.service.HiolabsOrderService;
import cn.outsourcing.supermarket.vo.*;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import javax.servlet.http.HttpServletRequest;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;

/**
 * 服务实现类
 *
 * @author gzkemays
 * @since 2021-10-14
 */
@Service
public class HiolabsOrderServiceImpl extends ServiceImpl<HiolabsOrderMapper, HiolabsOrder>
    implements HiolabsOrderService {
  @Resource HiolabsOrderMapper orderMapper;
  @Resource HiolabsOrderGoodsService orderGoodsService;
  @Resource private HttpServletRequest request;

  @Override
  public Result getOrderList(OrdersPageDTO entity) {
    return ResultUtils.pageResult(
        orderMapper.selectPage(
            IPageUtils.<HiolabsOrder>init().properties(entity),
            WrapperUtils.<HiolabsOrder>builder()
                .targetClazz(HiolabsOrder.class)
                .allEqByEntity(entity)));
  }

  @Override
  public PageResult<OrderVO> getOrderListVo(CommonPage page) {
    TimestampTransform timestampTransform = new TimestampTransform();
    IPageUtils<HiolabsOrder> properties = IPageUtils.<HiolabsOrder>init().properties(page);
    Integer userId =
        (Integer) JwtUtils.getTokenClaimByRequest(request, CommonConstants.TOKEN_USER_ID_KEY);
    List<Integer> statusList = new ArrayList<>();
    if (page.getShowType() == 0) {
      Collections.addAll(statusList, 101, 102, 103, 201, 202, 203, 300, 301, 302, 303, 401);
    } else if (page.getShowType() == 1) {
      // 待付款订单
      Collections.addAll(statusList, 101);
    } else if (page.getShowType() == 2) {
      // 待发货订单
      Collections.addAll(statusList, 201);
    } else if (page.getShowType() == 3) {
      // 待收货订单
      Collections.addAll(statusList, 301);
    } else if (page.getShowType() == 4) {
      // 待评价订单
      Collections.addAll(statusList, 302, 303);
    }
    // 获取分页数据
    List<HiolabsOrder> oldDatas =
        orderMapper
            .selectPage(
                properties,
                Wrappers.<HiolabsOrder>lambdaQuery()
                    .eq(HiolabsOrder::getUserId, userId)
                    .eq(HiolabsOrder::getIsDelete, 0)
                    .in(HiolabsOrder::getOrderStatus, statusList)
                    .ne(HiolabsOrder::getOrderType, OrderTypeEnums.RECHARGE.getNum())
                    .orderByDesc(HiolabsOrder::getAddTime))
            .getRecords();
    // 构造商品
    List<OrderVO> list = new ArrayList<>();
    for (HiolabsOrder data : oldDatas) {
      List<OrderGoodsVO> orderGoodsList = orderGoodsService.getOrderGoods(data.getId());
      OrderVO obj = HiolabsOrderConverter.INSTANCE.convertToDefaultVo(data);
      obj.setAddTime(timestampTransform.timestampToStringBySecond(data.getAddTime()))
          .setGoodsCount(orderGoodsList.size())
          .setGoodsList(orderGoodsList)
          .setOrderStatusText(OrderStatusEnums.DATA_MAP.get(obj.getOrderStatus()));
      list.add(obj);
    }
    return PageResultUtils.parseListPageObjs(properties, list);
  }

  /**
   * 获取订单详情
   *
   * @param orderId 订单id
   * @return 订单详情vo
   */
  @Override
  public OrderDetailVO getOrderDetail(Integer orderId) {
    TimestampTransform timestampTransform = new TimestampTransform();
    HiolabsOrder order =
        orderMapper.selectOne(
            Wrappers.<HiolabsOrder>lambdaQuery()
                .eq(HiolabsOrder::getId, orderId)
                .eq(HiolabsOrder::getIsDelete, 0));
    OrderInfoVO obj = HiolabsOrderConverter.INSTANCE.convertToInfoVo(order);
    long finalPayTime = DataUtils.getDayBeforeTimeStamp(1);
    long confirmRemainTime = DataUtils.getDayBeforeTimeStamp(3);
    // 未支付
    if (order.getPayTime() == 0) {
      obj.setPayTime("");
      obj.setFinalPayTime((int) finalPayTime);
    } else {
      obj.setPayTime(timestampTransform.timestampToStringBySecond(order.getPayTime()));
      obj.setConfirmRemainTime((int) confirmRemainTime);
    }
    obj.setAddTime(timestampTransform.timestampToStringBySecond(order.getAddTime()))
        .setOrderStatusText(OrderStatusEnums.DATA_MAP.get(order.getOrderStatus()));

    List<OrderGoodsVO> orderGoodsList = orderGoodsService.getOrderGoods(orderId);
    return OrderDetailVO.builder()
        .goodsCount(orderGoodsList.size())
        .handleOption(getOrderHandleOption(order.getOrderStatus()))
        .orderGoods(orderGoodsList)
        .orderInfo(obj)
        .textCode(getOrderTextCode(order.getOrderStatus()))
        .build();
  }

  /**
   * 逻辑删除订单
   *
   * @param dto dto对象
   * @return 逻辑删除行数
   */
  @Override
  public int deleteOrder(DeleteOrderDTO dto) {
    HiolabsOrder order = new HiolabsOrder();
    order.setId(dto.getOrderId());
    order.setIsDelete(1);
    return orderMapper.updateById(order);
  }

  /**
   * 关闭订单
   *
   * @param dto dto对象
   * @return 关闭订单行数
   */
  @Override
  public int cancelOrder(DeleteOrderDTO dto) {
    HiolabsOrder order = new HiolabsOrder();
    order.setId(dto.getOrderId());
    order.setOrderStatus(OrderStatusEnums.CANCELLED.getCode());
    return orderMapper.updateById(order);
  }

  @Override
  public int confirm(Integer orderId) {
    HiolabsOrder hiolabsOrder = orderMapper.selectById(orderId);
    hiolabsOrder.setOrderStatus(PayConstants.HAS_BEEN_COMPLETED);
    return orderMapper.updateById(hiolabsOrder);
  }

  @Override
  public WxSimulationPayVO updateFreeOrder(Integer orderId) {
    HiolabsOrder hiolabsOrder = orderMapper.selectById(orderId);
    Integer seconds = DataUtils.getSeconds();
    String prepay = "wx" + DataUtils.createRandomStr(34);
    hiolabsOrder.setOrderStatus(PayConstants.PAYMENT_HAS_BEEN);
    hiolabsOrder.setPayTime(seconds);
    orderMapper.updateById(hiolabsOrder);
    return WxSimulationPayVO.builder()
        .prepayId(prepay)
        .appId(new WechatProperties().getAppId())
        .timestamp(String.valueOf(seconds))
        .packageName("prepay_id=" + prepay)
        .signType("YZJCUSTOMER")
        .build();
  }

  @Override
  public OrderCountVO getOrderCount() {
    Integer userId =
        (Integer) JwtUtils.getTokenClaimByRequest(request, CommonConstants.TOKEN_USER_ID_KEY);
    return orderMapper.getOrderTypeCount(userId);
  }

  /**
   * 获取订单可操作的选项
   *
   * @param orderStatus 订单状态
   * @return 可操作选项列表
   */
  @Override
  public OrderHandleOptionVO getOrderHandleOption(Integer orderStatus) {
    OrderHandleOptionVO handleOption = new OrderHandleOptionVO();
    // 订单刚创建，可以取消订单，可以继续支付
    if (orderStatus == 101 || orderStatus == 801) {
      handleOption.setCancel(true);
      handleOption.setPay(true);
    }
    // 如果订单被取消
    if (orderStatus == 102 || orderStatus == 103) {
      handleOption.setDelete(true);
    }
    // 如果订单已付款，没有发货，则可退款操作
    if (orderStatus == 201) {
      // handleOption.return = true;
    }
    // 如果订单申请退款中，没有相关操作
    if (orderStatus == 202) {
      handleOption.setCancel_refund(true);
    }
    if (orderStatus == 300) {}
    // 如果订单已经退款，则可删除
    if (orderStatus == 203) {
      handleOption.setDelete(true);
    }
    // 如果订单已经发货，没有收货，则可收货操作,
    // 此时不能取消订单
    if (orderStatus == 301) {
      handleOption.setConfirm(true);
    }
    if (orderStatus == 401) {
      handleOption.setDelete(true);
    }
    return handleOption;
  }

  @Override
  public OrderTextCodeVO getOrderTextCode(Integer orderStatus) {
    OrderTextCodeVO result =
        OrderTextCodeVO.builder()
            .close(false)
            .countdown(false)
            .delivery(false)
            .pay(false)
            .receive(false)
            .success(false)
            .build();

    if (orderStatus == 101) {
      result.setPay(true);
      result.setCountdown(true);
    }
    if (orderStatus == 102 || orderStatus == 103) {
      result.setClose(true);
    }
    if (orderStatus == 201 || orderStatus == 300) { // 待发货
      result.setDelivery(true);
    }
    if (orderStatus == 301) { // 已发货
      result.setReceive(true);
    }
    if (orderStatus == 401) {
      result.setSuccess(true);
    }
    return result;
  }
}
